Staring under Marshmallow (Android 6), the Android OS is able to restrict individual permissions (which may or not be fine enough control for you) for an app. Under prior versions of Android, there was no ability to restrict a single permission; if you didn't like that an application used something, then you simply had to choose to uninstall the application.
You can inspect and change permissions under Settings->Apps->[Specific App Name]->Permissions. You can see the table of dangerous permissions that you are probably worried about. These permission categories cover the examples you have enumerated (contacts list -> contacts, call log -> phone, photos -> storage). Izzy has pointed out that there is no separate control for reading v. writing, which could be an issue if your application needs to write to storage but should not be able to view photos.
As Izzy has pointed out, there are some things you cannot control with these permissions, for example access to the randomly generated Android ID or internet access.
Whether an application still functions with a permission disabled depends on how it was written. Well written applications will continue to function in some way. Applications that are targeted to versions of Android before Marshmallow or that are simply poorly written may simply crash.
You can set permissions for Google Apps. You can for example:
- prevent the Photos application from reading storage, which means it will not be able to display your photos.
- prevent Gmail from reading your contacts
Using multiple users will not help you with privacy. When you install an application, this application is available for all users. You do not need to open an application for it to access your data. So while under user A the application cannot access user B's data, this does not really matter because the application can also run under user B while in the background.