Каким образом сайты делают многоязычными?
Какие существуют общепринятые приемы для переключения языка на сайте?
Вернее сказать подходы?

Локализация может быть статическая и динамическая.
Статическая:
полностью весь сайт локализован на сервере и живет себе копиями в какой-то папке site.com/
на которую ссылается поддомен либо же часть ссылки перенаправляет туда site.com/ru/content... ../by/content и т.д. или поддоменами тоже самое:
ru.site.com, by,site,com, или com.by, .com.ru как у гугла.

Очень геморно это поддерживать, т.к. руками придется переносить изменения текста из русского во все остальные варианты локализации.

Динамическая, опять же частичная и полная.
Частичная:
сервер отдает общие части сайта в запрошенном локализованном виде из url или поддомена или как угодно . Динамический контент версионируется по локализации. (В википедии так, общая часть хоть на шумерском, статьи можно переключать по языкам но они будут различаться с оригиналом).

Полностью динамическая локализация:
т.е. есть некий ru.json, en.json которые загружаются заранее/по запросу и оттуда берутся человеко-понятные слова и расставляются по всему сайту прямо в браузере по мере хождения по сайтам (современные SPA так работают), некоторые так не работают и надо собирать 2-6 вариантов локали сайта и хранить их в разных папках при каждом изменении исх. кода (так старый ангуляр работал, да и нынешний ничем не лучше без ngx-translate),
и собственно явно переключаешься по ним обращаясь к разным папкам-локалям. 

Контент... самое удобное - версионирование по языку и контенту (как это в википедии сделано).
Где есть начальная статья (пускай статья, контент короче), написанный на русском, кто-то переводит его на английский, потом на китайский и все это хранится в БД, и версионируется уже отдельно по изменениям. 
Естественно новое в русском не переместится в английский т.к. английская версия перестанет быть читабельной да и подача материала может быть иная. 

Является ли нормой создание нескольких виртуальных хостов под каждый язык?
почему нет. url-part может быть просто словом а уж веб-сервер разберется откуда реально взять информацию в нужной локали.
1. Если статический сайт, делать копии всего сайта на разных языках по папках. ТЕ при переходе в папку en/ с кореневой директории в папке en/ должен быть index.html на английском, и так все страницы.

2. На Wordpress если много плагинов, мои любимые это qTranslate-X + ACF очень хорошо справляются.

3. Поддомены для сайтов, также в качестве решения могут сгодиться, тут все просто. Даже на Wordpress есть плагин который делает эти поддомены и сам перенаправляет их