1. You don't have a lib file to link with - this is a pretty lame reason, since if you worked at it you could generate a LIB file. On the whole, though, generating a LIB file is probably more
work than just using LoadLibrary/GetProcAddress to dynamically load a DLL. A DLL may not always be present - if you want to provide for some graceful program degradation, you must dynamically load any DLL that may or may not be present on the target machine (example: UXTHEME.DLL, which exists only on XP). If you used implicit linking, your application would never have the chance to degrade gracefully - the system simply would not allow your app to start, and would instead display some alarming message to your user.
2. You need to support multiple feature sets - this is one of the historically valid reasons for using dynamic loading. If you have a product that supports many different features, and you
want to load only those features that the customer has paid for, then what you do is package
each feature set in its own DLL, and ship the DLL to the customer when he orders it. This is
also a very convenient way to add new features (read: plug-ins) to your product, essentially
making it open-ended.
3. You need to support multiple platforms - this is also one of the historically valid reasons for using dynamic loading. You need to support multiple platforms (Win98, Win2000, WinXP) and each platform requires slightly different code for some reason. A simple solution is to segregate the code for each platform in its own DLL.
4. You need to speed up the time it takes to load your application - this is another historical reason for using dynamic loading. You will start thinking about this when customers start complaining about how slow your app is to load. The idea is to identify what DLLs are necessary to display the core UI, and then dynamically load all the other DLLs that your app needs.