TL;DR: For some LiveChatTranscript records, CaseId is empty although standard Salesforce functionality is used and Case is created before Chat is ended.
Although this problem was already mentioned here, there wasn't any conclusion on root cause analysis.
Unfortunately, I'm facing exactly the same problem now and, because this is just a standard Salesforce feature, there's not much that end user can do about it. Salesforce Support Case is already reported but I'm wondering if you've encountered this problem as well.
This is especially problematic because there is no easy way to fix affected records because sometimes lack of CaseId might be normal but sometimes not so this requires a lot of manual effort to fix the data when we have dozens of hundreds of LiveChatTranscript records.