You pass p (parent) in the recursion to check where you came from.
function dfs(node, p):
for child in adj[node]:
if child != p:
dfs(child, node)
Call it with dfs(root, ) to start. The means "no parent" for the root. Every other node passes its own index as the parent when recursing to children.
This pattern is the foundation for most tree algorithms. Memorize it.