This is the best “guide” I’ve been able to find on this, which is to use Code.ensure_loaded?/1 with a module that you expect will be inside the optional dependency:
And one example of that approach being used is in Dataloader:
Although there’s no way to know for sure what a module will be in any given dependency, but generally there is a module that corresponds to the application name so this isn’t a large problem in practice.