Voilà l'exemple, j'avais une liste de Personne sous la main, dont 2 ont la même date de naissance.
mesPersonnes.Add(new Personne { Nom = "Sort", Prenom = "Jean", DateNaissance = DateTime.Parse("01/01/2001") });
mesPersonnes.Add(new Personne { Nom = "Dit", Prenom = "Alain", DateNaissance = DateTime.Parse("06/06/1990") });
mesPersonnes.Add(new Personne { Nom = "Zètofrais", Prenom = "Mélanie", DateNaissance = DateTime.Parse("01/01/2001") });
mesPersonnes.Add(new Personne { Nom = "Meliès", Prenom = "Georges", DateNaissance = DateTime.Parse("01/01/2000") });
mesPersonnes.Add(new Personne { Nom = "Alotre", Prenom = "Alain", DateNaissance = DateTime.Parse("02/01/2001") });
mesPersonnes.Add(new Personne { Nom = "Dupont", Prenom = "Tintin", DateNaissance = DateTime.Parse("01/02/2000") });
List<IGrouping<DateTime,Personne>> groupes = mesPersonnes.GroupBy(p => p.DateNaissance).ToList();
List<IGrouping<DateTime,Personne>> listeGroupesAuMoins2 = groupes.Where(g => g.Count() > 1).ToList();
Comme tu le vois sur la 1er capture "groupes" contient 5 enregistrements au lieu de 6 et le premier groupe contient bien les 2 personnes qui ont la même date de naissance.
Sur la seconde capture, il ne reste plus qu'un groupe, qui est bien celui avec 2 personnes.
Le résultat à ce stade est une liste de IGrouping<..>, donc une collection d'objets avec entre autre la propriété Key, qui est la propriété avec laquelle tu as groupé les données et la collection des items correspondant à cette Key.
Si ce format de données te convient, pas la peine d'aller plus loin.
Mais si tu veux une collection sans collection sous jacente, il faut une requête de plus
List<Personne> doublons = (from g in listeGroupesAuMoins2
from p in g
select p).ToList();
On peut faire tenir tout ça dans une seule instruction
List<Personne> doublons = mesPersonnes.GroupBy(p => p.DateNaissance).Where(g => g.Count() > 1).SelectMany(g => g).ToList();
Mais ça me parait plus lisible pour un débutant de décomposer.