Es una cuestión de optimización del consumo de memoria y una optimización de la comparación de cadenas. Cada vez que utiliza una cadena vacía en su aplicación, está asignando un objeto de cadena que contiene 0 caracteres. En cuanto a la comparación de cadenas, se puede hacer comparando referencias (punteros) en lugar de carácter por carácter, que es más rápido incluso para cadenas vacías.
Si usa muchas veces la misma cadena en su aplicación, puede usar el mismo tipo de mecanismo llamando a String.Intern () con su cadena. Pero si usa cada cadena solo una vez, solo usará más memoria.
Entonces, String.Empty es solo una optimización de casos especiales que vale la pena hacer para la mayoría de las aplicaciones .Net, por eso se integró en el BCL.
Para más detalles sobre este tema, recomiendo leer la publicación del blog de Eric Lippert .
También debe echar un vistazo a esta documentación a la que hace referencia su publicación de blog.