Your 2. point is still confusing me. You say that

[…] and intermediary results. Without these, the “graph” cannot be used for anything […]

To what parts of the graph does this refer? Does it refer to the entire graph that was tracked through backpropagation? And what does “anything” mean in that context? What else than gradient computation would / could you use a graph for?
I tried the following snippet where a graph is constructed (up to c), then backproped and then the graph’s upper part (by d, or even the whole graph by e) is reused for construction of another graph. Based on the above statement that .backward() frees any resources / buffers / intermediary results of the graph, I would expect the computation of d and e not to work (i.e. not only backprop), but apparently it does:
a = torch.tensor(1, requires_grad=True)
b = a * torch.tensor(2)
c = b * torch.tensor(3)

c.backward()

d = b * torch.tensor(4)
e = c * torch.tensor(5)
print('d = ', d)
print('e = ', e)

So it still remains unclear to me what things, after performing .backward(), the graph (or parts of it) can be used for and what things it cannot be used for anymore (another .backward() for example). Like a list of do’s and don’t’s after a graph has been backproped (considering operations involving that graph).