I find it helpful to organise namespaces into a hierarchy, and make the assembly names match the subnamespace they contribute to. For example, a project called Womble would have a top-level namespace Womble, and then there might be assemblies called:
Womble.ClientLibrary.dll
Womble.Controls.dll
Womble.Util.dll
Womble.Interop.dll
Here, the outer Womble namespace spans multiple assemblies, but each assembly has a unique subnamespace that only it can contribute to, which you find by removing .dll from the end. It makes it a lot easier to remember what you need to reference and to find things.
As for very large numbers of assemblies, ultimately you don't need to keep them all in one solution. In large scale development it helps to break up a big product into subsystems, which may themselves consist of multiple assemblies, and each subsystem may end up being maintained by separate teams, and can have their own solution files. The various teams "release" new versions to each other via source control, treating each other as third party libraries.
I don't think there is a hard and fast way to decide how to break up software into aseemblies. There's a general principle here: things that change for different reasons should be separated.
Very large projects can gain from the fact that by putting things in separate assemblies, you are able to patch them separately. You can produce a hotfix for an issue in Womble.Interop.dll, and then separately produce a hotfix for an issue in Womble.Controls.dll, and give both to the same customer, so that in theory, those two assemblies could be completely maintained and supported by separate teams, without having to coordinate their activities directly.
Separate assemblies also create clarity in the dependencies between code. You can see at a very high level (just looking at the references list) how one chunk of code depends on another, and how it might be reused. If you put everything in one assembly, it might be one big tangled mess with no sensible pattern to it.