JavaScript — как проверить, есть ли в объекте циклические ссылки?
Поиск в глубину.

Надо поддерживать список/множество уже посещенных вершин и пока посещаемых (те, что в стеке). При заходе в вершину в рекурсивной функции помещайте ее в множество пока посещаемых. При возвращении из функции перемещайте вершину в множество уже посещенных. В функции пройдитесь по всем ребрам, если они ведут в пока посещаемую вершину - вы нашли цикл. Если ребро ведет в уже посещенную - игнорируйте его. Если ребро ведет в не посещенную вершину - рекурсивно запускайтесь от нее.
Написал иллюстрацию, как такой обход организовать и посмотреть что происходит в каждый шаг. При желании и небольшом старании можете преобразовать функцию под условия задачи

Код
const data = {
  "index.js": ["foo.js"],
  "foo.js": ["baz.js", "lol.js"],
  "baz.js": ["bar.js", "lem.js"],
  "bar.js": ["baz.js", "k.js"]
};

function searchCircularDepengency(entry = "index.js", path = []) {
  const branch = data[entry];
  const newPath = [...path, entry];

  console.log("Path", newPath);

  // Если есть вложенные элементы,
  if (branch) {
    // проверить каждый
    branch.forEach((nextEntry) => {
      // на предмет прохожения ранее,
      if (path.includes(nextEntry)) {
        console.warn(
          "Found Circular Depengency " + nextEntry + " in " + entry,
          path
        );
        // если нет идти глубже
      } else {
        searchCircularDepengency(nextEntry, newPath);
      }
    });
  } else {
    console.log("Branch complite. All OK!");
  }
}

console.log(searchCircularDepengency());

В песочнице