Note: In case it matters, we are using git, (so branching and merging is a breeze), and this is an Android application (Java - so conditional compilation is not really applicable).
Similar to this question here, but what if you have more than just UI differences between different rebrands of a single version of your software? For example, what if an entire feature or subsystem should not be compiled into one of the rebrands (e.g. it contains code that is intellectual property of one company and should not be available to others)?
Should a separate branch be created for each rebrand in this case? If so, is there any use for a main/master branch, since it will just become code-storage and not compile into any useful application (weird)? But not having a main/master branch means having to cherry-pick (individually select) commits to merge across rebrands, which seems like a bad approach.
Or is there another way to solve this that doesn't involve branches?
From the information provided in Your question, I'd recomment not using branches.
Branches will divert unless merged. Therefore, making a bugfix available in all branches will require a lot of cherry-picking or at least very careful commit/merge handling.
What about putting customer-specific code into libraries that are loaded by the application?
Pro:
Con: