I would say that you have a very difficult task ahead of you.
AFAIK, the officially supported way of separating data between different customers in Salesforce is to create different orgs. I assume that you have discarded that for some reason.
Answers to your specific questions
1. how to hide data of Customer A from Customer B
The only way I can think so to hide records between users is to set the org-wide sharing defaults to 'private' and give access through hierarchies. Then you would model each customer as a department in the hierarchy tree: put all the users from a customer into one branch of the hierarchy tree.
You can also try to create a sharing rule so that records are shared with members of the same 'department' (ie: all the users from one customer in the hierarchy tree).
2. how to prevent Customer B seeing the users from Customer A
See above
3. use of permissions sets vs role hierarchy or sharing rules
Permission sets can only add permissions to a user. They can't restrict them. So I think that role hierarchy and sharing rules are the way to go.
4. use of Delegated Administrator to allow customers Admins create users
The moment you give any customer admin permissions, there is nothing preventing him from giving himself permissions to access all data. I can't think of another way to give a user permissions to create other users without being an admin.
5. adaption of standard functionality like case processes
I would have to give more thought to this depending on the implementation you choose.
I think I have answered your questions. However, I would strongly discourage this approach. One single misconfiguration and users will be able to see each other's data. The way to go for this is to have each customer have their own organisation, and deployed your code to all the orgs via a package.