The proper way is to look at the HTTP Accept-Language header sent to the server. This contains the ordered, weighted list of languages the user has configured their browser to prefer.
navigator.language, which tells you what localised version of the web browser was installed. This is not necessarily the same thing as the user's preferred language(s). On IE you instead get
systemLanguage (OS installed language),
browserLanguage (same as
userLanguage (user configured OS region), which are all similarly unhelpful.
If I had to choose between those properties, I'd sniff for
userLanguage first, falling back to
language and only after that (if those didn't match any available language) looking at
browserLanguage and finally
var acceptLanguage= 'en-gb,en;q=0.7,de;q=0.3';
Whatever you end up doing, you certainly need a user override because it will always guess wrong for some people. Often it's easiest to put the language setting in the URL (eg. http?://www.example.com/en/site vs http?://www.example.com/de/site), and let the user click links between the two. Sometimes you do want a single URL for both language versions, in which case you have to store the setting in cookies, but this may confuse user agents with no support for cookies and search engines.