code: private void traverseAndRemoveUnusedReferences(Node root) {
      // Create scope from parent of root node, which also has externs as a child, so we'll
      // have extern definitions in scope.
      Scope scope = scopeCreator.createScope(root.getParent(), null);
      if (!scope.hasSlot(NodeUtil.JSC_PROPERTY_NAME_FN)) {
        // TODO(b/70730762): Passes that add references to this should ensure it is declared.
        // NOTE: null input makes this an extern var.
        scope.declare(
            NodeUtil.JSC_PROPERTY_NAME_FN, /* no declaration node */ null, /* no input */ null);
      }
      worklist.add(new Continuation(root, scope));
      while (!worklist.isEmpty()) {
        Continuation continuation = worklist.remove();
        continuation.apply();
      }
  
      removeUnreferencedVarsAndPolyfills();
      removeIndependentlyRemovableProperties();
      for (Scope fparamScope : allFunctionParamScopes) {
        removeUnreferencedFunctionArgs(fparamScope);
      }
    }
docs: Traverses a node recursively. Call this once per pass.