Browser makers are actively patching browser bugs that let sites identify private mode. Some bugs remain, but code to detect them is unlikely to be worth writing as the plan is it won't work for long.
The reason why browser makers are fixing these bugs is that sites like news publishers are using the bugs to identify private-mode users and refuse to serve them. The news publishers who want to do this tend to be using "metered paywalls", which let each browser view a certain number of free articles per day (or per week or whatever) and then start charging: since private-mode effectively resets the meter, the publishers don't want you to use private mode. But restricting private mode also restricts people who want to use it for other reasons, e.g. a domestic-abuse victim not wanting to keep history on a browser shared with their abuser, or someone not wanting their current activity to affect what advertisements they see in future, or some other reason. Although news sites that restrict private mode do tend to permit it if you log in, it's rather obvious that logging in lets them track you, so if you're trying to avoid being tracked then logging-in doesn't seem like an acceptable solution, hence browser makers want publishers not to be able to detect private mode.
There is another way of not keeping history: use a browser that lets you selectively clear it afterwards. Chrome for example can clear cookies, cache and history associated with specific domains, or for a specified period of time such as "for the last hour". That way you don't need private or incognito mode: you can get the same effect by browsing in normal mode and then erasing the traces. But you have to know how to do it, plus you must remember to do it, so it's a more troublesome approach than is using private mode. Still, I expect some people are using this as a workaround if their browser still has a bug that lets sites detect when they're in private mode and deny them service.
If you as a website author have a reason for not wanting your website to be stored in cache or history, for example if the site is meant to help domestic-abuse victims, then "how to detect private mode" might be the wrong question, as what you really want is "don't store this stuff in history, whether private mode is in use or not". Chris Coyier on css-tricks.com noted that window.location.replace() does not create a history item and techniques like this could be used to construct a site that at least doesn't leave its individual pages in history (at least not when browsed with Javascript switched on), but the referring page—possibly a dangerous-to-have search-result page—would still be in history, as would the final page they were on if they don't properly "sign out" of the site. (Intermediate pages might also be discernible via cache forensics, but anyone who can do that can probably also record the traffic as it happens, so we just have to hope the abuser is not that clever.) Another possible approach might be to create an innocent-looking cookie that stores the timestamp of the page's first load, and replace its content with something else if the current time exceeds that timestamp by too long, although its URL may still be loadable on another device or by clearing cookies (unless it was also session-dependent). But getting rid of the referring page is still going to be an issue, and as it's not always possible to confirm the user is in private mode, the best policy is probably to take steps to educate them about private mode anyway.
If you check their User-Agent, you can show them what both private mode and non private mode look like on their browser and OS, ask them to confirm which of the two matches their current window right now, and caution them if they choose the non private mode appearance. This won't work for browser and OS combinations you didn't test (but then neither will bug-based detection), and it assumes the user cares about their security enough to take the question seriously—but if they don't, the battle is probably already lost anyway.