For dynamic programming problems, how do we know the subproblems will share subproblems?
The answer is - you don't.  Not in advance.  There are no guarantees and there is no silver bullet process.
Instead, dynamic programming is a way of thinking about a problem, a framework for approaching a problem.  You typically won't know whether that approach will be successful or not in advance.
Dynamic programming basically amounts to finding a recursive algorithm for the problem, and then speeding it up with memoization.  You'll have to try different recursive algorithms (different ways of decomposing into subproblems) and see, for each candidate, if it has the properties that are needed to apply these ideas successfully.  You usually won't know in advance whether any particular decomposition into subproblems will be successful.   You might be able to tell whether those subproblems will be &quot;overlapping&quot;, but not whether it'll lead to a useful dynamic programming algorithm.  It's partly an art, where experience helps give you some intuitions for what kinds of subproblems might be useful in any particular situation.
I encourage reading What is dynamic programming about?, When can I use dynamic programming to reduce the time complexity of my recursive algorithm?, and Deciding on Sub-Problems for Dynamic Programming to get a sense of this perspective.
Personal opinion: I personally don't find &quot;overlapping subproblems&quot; as a very helpful way to think about dynamic programming.  I encourage you to use whatever works for you, but that one never worked very well for me.  If you want to understand it, think about algorithms that work on an array $A[1..n]$.  Divide-and-conquer will work on some subarrays, say $A[1..n/2],A[n/2+1..n],\ldots$, but no pair of those have a partial overlap.  Dynamic programming may work on all subarrays, say $A[i..j]$ for all $i&lt;j$, and there are pairs of those that partly overlap (e.g., $A[3..5]$ overlaps with $A[4..9]$).  That's what is meant by &quot;overlapping subproblems&quot;, and that is one distinction between dynamic programming vs divide-and-conquer.  That said, I don't find that a very helpful characterization, personally -- and especially, I don't find it helpful at designing an algorithm (it might be more helpful once I already have an algorithm and am wondering whether I should call it divide-and-conquer vs dynamic programming, but at that point I often don't care too much what we call it).