(I have not read Clean Code and don't know much Java.)
Does it make sense to apply the idea of creating many tiny entities, each with a clearly define responsibility, to namespaces?
Yes, just as it does with refactoring into multiple classes and multiple functions.
Should a small group of related classes always be wrapped in a namespace?
Without actually answering: yes, you should at least use one top-level namespace. This can be based on project, organization, or whatever you like, but using few global names will reduce name conflicts. A single namespace to group everything else under it only introduces one global name. (Excepting extern "C" functions, but that's due to C interoperability and only affects other extern "C" functions.)
Should a small group of related classes be wrapped in a namespace dedicated to them? Probably. Especially if you find yourself using a common prefix on those classes – FrobberThing, FrobberThang, FrobberDoohickey – you should consider a namespace – frobber::Thing and so on. This would still be under your root namespace or another namespace if they are part of a larger project.
Is this the way to manage the complexity of having lots of tiny classes, or would the cost of managing lots of namespaces be prohibitive?
Taking the above example of prefixed names, it isn't harder to manage frobber::Thing than FrobberThing. It may even be easier with some tools, such as documentation and code completion. There is a difference with ADL, but this can work in your favor: fewer names in associated namespaces make ADL simpler to figure out, and you can put using declarations to inject specific names into one namespace or another.
Namespace aliases allow you to use a shorter name for a longer namespace in a specific context, which again allow easier use:
void f() {
namespace CWVLN = Company_with_very_long_name; // Example from the standard.
// In this scope, use CWVLN::name instead of Company_with_very_long_name::name.
namespace fs = boost::filesystem; // Commonly used.
}
Consider Boost, which has a single root namespace, boost, and then many subnamespaces – boost::asio, boost::io, boost::filesystem, boost::tuples, etc. – for various libraries. Some names are "promoted" to the root namespace:
All definitions are in namespace ::boost::tuples, but the most common names are lifted to namespace ::boost with using declarations. These names are: tuple, make_tuple, tie and get. Further, ref and cref are defined directly under the ::boost namespace.
The biggest difference from languages with "real" modules is how common it is to use a flatter structure, which mostly happens because that's how it works unless you take extra, specific effort to define nested names.