$(HOME)/lib:/usr/local/lib:/lib:/usr/lib
You'll notice that those fallback paths do not include any location relative to the application. It's actually pretty difficult to get the object code to lookup libraries relative to its own directory. Explanation here:
https://birchlabs.co.uk/blog/alex/juicysfplugin/synth/cpp/20...
The program sets LD_RUNPATH_SEARCH_PATHS which bakes a list of paths into the binary. This can include relative paths as well as @loader_path and @executable_path. eg a plugin bundled with an app can specify @executable_path/../../Frameworks to reference the parent bundle's Frameworks directory. Libraries can also add search paths to help locate their dependencies. @loader_path will expand relative to the library that actually has the dependency.
Any linked library with a DYLD name of @rpath/ will be searched in those locations.
At build time the linker checks each library for its DYLD name and bakes that name into the final binary. Making sure all of your non-system dependencies are @rpath and relative to your app bundle is what makes it a "Relocatable" application.
One could just use a wrapper script that sets the DYLD_FALLBACK_LIBRARY_PATH relative to the binary's directory and run it.