Strong versioning is key. Only allow links to be redirected to bug fixes, never feature enhancements. If you wrote your code for 1.0, you'll continue to link against 1.0, barring some bug fix (1.0.1). Your code should never be silently upgraded to link against 1.1. Microsoft also gets this right with the global assembly cache.
As an aside, DLL Hell was coined by Szyperski, who still works for Microsoft.
Well they are dynamically linked but usually only to Apple provided libraries as far as I know. It's not like every app installs a dozen new dlls to your system and that's what makes the big difference. It's what makes Mac apps (at least traditionally) standalone and executable from anywhere.
I fear however, that Apple is currently destroying this design philosophy with the sandboxing. At least the application data folders have become way more complex now and I wouldn't like to troubleshoot them anymore, something that has been always been super easy.
Technically, outside of Apple frameworks, they're typically dynamically linked to frameworks located inside the .app folder. This is by no means mandatory though.